﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace MS.Common
{
    /// <summary>
    /// VisualTree工具类
    /// </summary>
    public static class VisualTreeTool
    {
        /// <summary>
        /// 查找父控件的子控件集合
        /// </summary>
        /// <typeparam name="T">子控件类型</typeparam>
        /// <param name="obj">父控件</param>
        /// <param name="typename">子控件类型</param>
        /// <returns></returns>
        public static List<T> GetChildObjects<T>(DependencyObject obj, Type typename) where T : FrameworkElement
        {
            DependencyObject child = null;
            List<T> childList = new List<T>();

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child is T && (((T)child).GetType() == typename))
                {
                    childList.Add((T)child);
                }
                childList.AddRange(GetChildObjects<T>(child, typename));
            }
            return childList;
        }
        /// <summary>
        /// 查找父控件的子控件集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="typename"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static T GetChildObjects<T>(DependencyObject obj, Type typename, String name) where T : FrameworkElement
        {
            List<T> childList = GetChildObjects<T>(obj, typename);
            if (childList == null || childList.Count == 0)
            {
                return null;
            }
            return childList.Where(A => A.Name == name).FirstOrDefault();
        }

        /// <summary>
        /// 获取根父节点
        /// </summary>
        /// <returns></returns>
        public static FrameworkElement GetParentFramework(this FrameworkElement child)
        {
            if (child == null)
            {
                return null;
            }
            if (child.Parent == null)
            {
                return child;
            }
            return GetParentFramework(child.Parent as FrameworkElement);
        }

        /// <summary>
        /// 获取当前控件所属的Window窗口
        /// </summary>
        /// <param name="ui"></param>
        /// <returns></returns>
        public static Window GetBaseWindow(this FrameworkElement ui)
        {
            if (ui == null)
            {
                return null;
            }
            if (ui as Window != null)
            {
                return ui as Window;
            }
            if (ui.Parent == null)
            {
                return null;
            }
            if (ui.Parent as Window != null)
            {
                return ui.Parent as Window;
            }
            return GetBaseWindow(ui.Parent as FrameworkElement);
        }

        /// <summary>
        /// 获取指定类型的父级控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="typename"></param>
        /// <returns></returns>
        public static T GetParentFrame<T>(FrameworkElement obj, Type type) where T : FrameworkElement
        {
            if (obj == null)
            {
                return null;
            }
            if (obj.GetType().FullName == type.FullName)
            {
                return (T)obj;
            }
            return GetParentFrame<T>(obj.Parent as FrameworkElement, type);
        }

        /// <summary>
        /// 设置表格样式的Border样式
        /// </summary>
        /// <param name="ui"></param>
        public static void SetTableBorderStyle(this FrameworkElement ui)
        {
            List<Border> lst_border = VisualTreeTool.GetChildObjects<Border>(ui, typeof(Border));
            if (lst_border == null || lst_border.Count == 0)
            {
                return;
            }
            foreach (Border border_item in lst_border)
            {
                border_item.Style = Application.Current.Resources["TableBorderStyle"] as Style;
            }
        }

        /// <summary>
        /// 设置表格样式的Border样式
        /// </summary>
        /// <param name="ui"></param>
        public static void SetTableBorderStyle2(this FrameworkElement ui)
        {
            List<Border> lst_border = VisualTreeTool.GetChildObjects<Border>(ui, typeof(Border));
            if (lst_border == null || lst_border.Count == 0)
            {
                return;
            }
            foreach (Border border_item in lst_border)
            {
                border_item.Style = Application.Current.Resources["TableBorderStyle2"] as Style;
            }
        }

        /// <summary>
        /// 设置基本公卫查询区域下的Border、TextBlock样式
        /// </summary>
        /// <param name="ui"></param>
        public static void SetJbgwSearchTableStyle(this FrameworkElement ui)
        {
            if (ui as Panel == null)
            {
                return;
            }
            foreach (UIElement item in (ui as Panel).Children)
            {
                if (item.GetType().Name == typeof(Border).Name)
                {
                    (item as Border).Style = Application.Current.Resources["TableBorderStyle2"] as Style;
                    continue;
                }
                if (item.GetType().Name == typeof(TextBlock).Name)
                {
                    (item as TextBlock).Style = Application.Current.Resources["JbgwTextBlockStyle"] as Style;
                    continue;
                }
            }
        }


        /// <summary>
        /// 设置DataGrid鼠标滑轮事件向上路由
        /// </summary>
        /// <param name="ui"></param>
        public static void SetScrollViewerRaiseEvent(this FrameworkElement ui)
        {
            List<DataGrid> tmp_lst_datagrid = GetChildObjects<DataGrid>(ui, typeof(DataGrid));
            if (tmp_lst_datagrid == null)
            {
                return;
            }
            ScrollViewer tmp_scrollview = GetParentFrame<ScrollViewer>(ui, typeof(ScrollViewer));
            if (tmp_scrollview == null)
            {
                return;
            }
            foreach (DataGrid item in tmp_lst_datagrid)
            {
                item.PreviewMouseWheel += (ws, we) =>
                {
                    MouseWheelEventArgs eventMouseWheel = new MouseWheelEventArgs(we.MouseDevice, we.Timestamp, we.Delta);
                    eventMouseWheel.RoutedEvent = UIElement.MouseWheelEvent;
                    eventMouseWheel.Source = tmp_scrollview;
                    if (eventMouseWheel != null)
                    {
                        tmp_scrollview.RaiseEvent(eventMouseWheel);
                    }
                };
            }
        }

        //#region 数据验证

        ///// <summary>
        ///// 设置数据验证
        ///// </summary>
        ///// <param name="ui"></param>
        //public static void SetValidation(this FrameworkElement ui)
        //{
        //    if (ui == null)
        //    {
        //        return;
        //    }
        //    //if (ui as Grid != null)
        //    //{
        //    //    ControlTemplate template = Application.Current.Resources["NULL_Validation_ErrorTemplate"] as ControlTemplate;
        //    //    if (template != null)
        //    //    {
        //    //        System.Windows.Controls.Validation.SetErrorTemplate(ui, template);
        //    //    }
        //    //}
        //    System.Windows.Controls.Validation.RemoveErrorHandler(ui, Element_Error);
        //    System.Windows.Controls.Validation.AddErrorHandler(ui, Element_Error);
        //}
        ///// <summary>
        ///// 数据验证事件
        ///// </summary>
        ///// <param name="sender"></param>
        ///// <param name="e"></param>
        //private static void Element_Error(object sender, ValidationErrorEventArgs e)
        //{
        //    if (e.Action != ValidationErrorEventAction.Added)
        //    {
        //        return;
        //    }
        //    FrameworkElement element = sender as FrameworkElement;
        //    if (element == null)
        //    {
        //        MessageBox.Show(e.Error.ErrorContent.ToString(), "提示");
        //        return;
        //    }
        //    MessageBoxEx.Show(element, e.Error.ErrorContent.ToString());
        //}

        //#endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public static class MessageBoxEx
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="messageBoxText"></param>
        /// <returns></returns>
        public static MessageBoxResult Show(FrameworkElement owner, String messageBoxText, MessageBoxImage icon = MessageBoxImage.None)
        {
            return Show(owner, messageBoxText, "", MessageBoxButton.OK, icon);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="messageBoxText"></param>
        /// <param name="caption"></param>
        public static MessageBoxResult Show(FrameworkElement owner, String messageBoxText, String caption, MessageBoxImage icon = MessageBoxImage.None)
        {
            return Show(owner, messageBoxText, caption, MessageBoxButton.OK, icon);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="messageBoxText"></param>
        /// <param name="button"></param>
        /// <returns></returns>
        public static MessageBoxResult Show(FrameworkElement owner, String messageBoxText, MessageBoxButton button, MessageBoxImage icon = MessageBoxImage.None)
        {
            return Show(owner, messageBoxText, "", button, icon);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="messageBoxText"></param>
        /// <param name="caption"></param>
        /// <param name="button"></param>
        public static MessageBoxResult Show(FrameworkElement owner, String messageBoxText, String caption, MessageBoxButton button, MessageBoxImage icon = MessageBoxImage.None)
        {
            if (String.IsNullOrEmpty(caption))
            {
                caption = "提示";
            }
            if (owner == null)
            {
                owner = Application.Current.MainWindow;
            }
            if (owner as Window != null)
            {
                return System.Windows.MessageBox.Show(owner: owner as Window, messageBoxText: messageBoxText, caption: caption, button: button, icon: icon);
            }
            Window win_owner = owner.GetBaseWindow();
            if (win_owner == null)
            {
                return System.Windows.MessageBox.Show(messageBoxText, caption, button: button);
            }
            return System.Windows.MessageBox.Show(owner: win_owner, messageBoxText: messageBoxText, caption: caption, button: button, icon: icon);
        }
    }
}

